package top.tenebrous.yzl.im.handler;

import com.alibaba.fastjson.JSONException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
import top.tenebrous.yzl.im.ImChatProcessor;
import top.tenebrous.yzl.im.context.ImContext;
import top.tenebrous.yzl.im.enums.ChatType;
import top.tenebrous.yzl.im.enums.MessageType;
import top.tenebrous.yzl.im.factory.message.MessageFactory;
import top.tenebrous.yzl.im.interceptor.ImWebsocketInterceptor;
import top.tenebrous.yzl.im.message.AuthRequestMessage;
import top.tenebrous.yzl.im.message.AuthResponseMessage;
import top.tenebrous.yzl.im.message.MessageChatList;
import top.tenebrous.yzl.im.model.*;
import top.tenebrous.yzl.im.utils.WebSocketUtils;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * websocket连接时，权限认证，session处理，群组查询等
 *
 * @author yazhang6
 */
@Slf4j
@Component
public class WebSocketOpenMessageHandler implements MessageHandler<AuthRequestMessage>, InitializingBean {

    @Autowired
    private MessageFactory messageFactory;

    @Autowired
    private ImChatProcessor imChatProcessor;

    @Autowired
    private ImContext imContext;

    @Override
    public void execute(WebSocketSession webSocketSession, AuthRequestMessage message) {
        try {
            String sessionNo = message.getSessionNo();
            if (StringUtils.isEmpty(message.getUserId())) {
                WebSocketUtils.send(webSocketSession, message.getType(), null);
                return;
            }

            // 判断当前用户是否已经登录
            WebSocketSession socketSession = WebSocketUtils.getSession(message.getUserId());
            if (Objects.nonNull(socketSession)) {
                log.info("{}:当前用户已登录!", sessionNo);
                // TODO 是否踢出下线
                WebSocketUtils.sendError(webSocketSession, message.getType(), "当前账号异地登录，您已被强制下线",message.getUserId());
                WebSocketUtils.removeSession(socketSession);
            }
            // 获取用户信息
            log.info("{}:加载用户信息中....", sessionNo);
            ImClientUserBean imClientUserBean = imChatProcessor.takeAfterChatUserInfo(message.getUserId());
            if (Objects.isNull(imClientUserBean)) {
                log.error("{}:当前用户不存在", sessionNo);
            }

            // 获取用户朋友信息
            log.info("{}:======> 加载置顶用户朋友信息中....", sessionNo);
            List<ImClientChatListBean> topChatList =
                imChatProcessor.takeAfterChatListTopInfo(message.getUserId());
            log.info("{}:======>加载置顶用户朋友信息完成", sessionNo);

            log.info("{}:======>加载非置顶用户朋友信息中....", sessionNo);
            List<ImClientChatListBean> notTopChatList =
                imChatProcessor.takeAfterChatListInfo(message.getUserId());
            log.info("{}:======>加载非置顶用户朋友信息完成....", sessionNo);

            // 获取群组id加入session池
            Set<String> grouIds = new HashSet<>();
            Set<String> topGroupIds = topChatList.stream()
                .filter(item -> Objects.equals(item.getChatType(), ChatType.PUBLIC_CHAT_TYPE.getCode()))
                .map(ImClientChatListBean::getId).collect(Collectors.toSet());

            Set<String> notTopGroupIds = notTopChatList.stream()
                .filter(item -> Objects.equals(item.getChatType(), ChatType.PUBLIC_CHAT_TYPE.getCode()))
                .map(ImClientChatListBean::getId).collect(Collectors.toSet());
            grouIds.addAll(topGroupIds);
            grouIds.addAll(notTopGroupIds);
            WebSocketUtils.addSession(webSocketSession, imClientUserBean, new ArrayList<>(grouIds));


            // 循环发送消息
            for (ImClientChatListBean bean : topChatList) {
                MessageChatList chatList = buildMessageBean(bean);
                WebSocketUtils.send(webSocketSession, chatList.getType(), chatList);
            }

            for (ImClientChatListBean bean : notTopChatList) {
                MessageChatList chatList = buildMessageBean(bean);
                WebSocketUtils.send(webSocketSession, chatList.getType(), chatList);
            }

            // 给予响应
            log.info("{}:加载数据完成....", sessionNo);
        } catch (JSONException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static MessageChatList buildMessageBean(ImClientChatListBean bean) {
        MessageChatList chatList = new MessageChatList();
        chatList.setChatId(bean.getId());
        chatList.setChatType(bean.getChatType());
        chatList.setChatName(bean.getNote());
        chatList.setImageUrl(bean.getImageUrl());
        chatList.setUniqueId(bean.getUniqueId());
        chatList.setTopFlag(bean.getTopFlag());
        chatList.setSystemNotice(bean.getSystemNotice());
        ImClientChatInfoBean clientChatInfoBean = new ImClientChatInfoBean();
        clientChatInfoBean.setFromUserName(bean.getLastSendName());
        clientChatInfoBean.setLastMessage(bean.getContent());
        clientChatInfoBean.setLastMessageDate(bean.getShowLastChatTime());
        // TODO 暂时保留
        //                clientChatInfoBean.setIsRead();
        //                clientChatInfoBean.setNotReadNum();

        chatList.setImClientChatInfo(clientChatInfoBean);
        return chatList;
    }

    @Override
    public String getType() {
        return MessageType.AUTH.getCode();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        messageFactory.register(MessageType.AUTH, this);
    }
}
